#!/bin/sh
# Copyright 2013 IBM, Inc.
# Copyright 2017-2020 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# Refer to the README and COPYING files for full details of the license
#

VDSM_TOOL="@BINDIR@/vdsm-tool"
UPGRADE_LOGGING_PARAMS="--vvverbose --append --logfile=@VDSMLOGDIR@/upgrade.log"
prog=vdsm

#### pre-start tasks ####
task_configure_vdsm_logs() {
    local vdsm_logs="
        @VDSMLOGDIR@/mom.log
        @VDSMLOGDIR@/vdsm.log
    "
    local wanted_mode="0644"
    local wanted_owner="@VDSMUSER@:@VDSMGROUP@"

    for logfile in ${vdsm_logs}; do
        if [ ! -e "${logfile}" ]; then
            @TOUCH_PATH@ "${logfile}"
            @CHMOD_PATH@ "${wanted_mode}" "${logfile}"
            @CHOWN_PATH@ "${wanted_owner}" "${logfile}"
        else
            owner=$(stat -c %U:%G "${logfile}")
            fmode=$(stat -c 0%a "${logfile}")
            if [ "${owner}" != "${wanted_owner}" ]; then
                echo "Warning: log file ${logfile} is owned by ${owner}... Fixing..."
                @CHOWN_PATH@ "${wanted_owner}" "${logfile}"
            fi
            if [ "${fmode}" != "${wanted_mode}" ]; then
                echo "Warning: bad file access mode for log file ${logfile} : ${fmode}... Fixing..."
                @CHMOD_PATH@ "${wanted_mode}" "${logfile}"
            fi
        fi
    done
}

task_run_init_hooks(){
    "@PYTHON@" -m "vdsm.common.hooks" before_vdsm_start
}


task_check_is_configured() {
    "$VDSM_TOOL" is-configured
}


task_prepare_transient_repository() {
    "$VDSM_TOOL" setup-transient-repository
    "$VDSM_TOOL" cleanup-transient-repository
}


task_syslog_available() {
    if ! [ -S "/dev/log" ]; then
        echo "    Cannot communicate with syslog daemon for reports. "
        echo "    Install syslog daemon provider, configure it properly"
        echo "    and start the service."
        echo "    (Alternatives: rsyslog, syslog-ng)"
        return 1
    fi
    return 0
}


task_nwfilter(){
    "${VDSM_TOOL}" nwfilter
}


task_dummybr(){
    "${VDSM_TOOL}" dummybr
}


_has_systemd() {
    "@MOUNTPOINT_PATH@" -q /cgroup/systemd ||
        "@MOUNTPOINT_PATH@" -q /sys/fs/cgroup/systemd
}


task_dump_bonding_options(){
    "${VDSM_TOOL}" dump-bonding-options
}


task_tune_system(){
    "@SYSCTL_PATH@" -q -p "/etc/sysctl.d/vdsm.conf"
}


_CONF_FILE="@CONFDIR@/vdsm.conf"
_GETCONFITEM="@LIBEXECDIR@/get-conf-item"

_mk_data_center() {
    local dc
    dc="$("${_GETCONFITEM}" "${_CONF_FILE}" irs repository /rhev/)"
    @MKDIR_P@ "${dc}"
    "@CHOWN_PATH@" @VDSMUSER@:@VDSMGROUP@ "${dc}"
}

_mk_run_path() {
    local run_path

    for run_path in "@VDSMRUNDIR@"; do
        @MKDIR_P@ "${run_path}"
        "@CHMOD_PATH@" 755 "${run_path}"
        "@CHOWN_PATH@" @VDSMUSER@:@VDSMGROUP@ "${run_path}"
        "@RESTORECON_PATH@" "${run_path}"
    done
}

_mk_console_path() {
    local console_path=/var/run/ovirt-vmconsole-console
    if ! [ -d "${console_path}" ]; then
        @MKDIR_P@ "${console_path}" > /dev/null 2>&1
    fi
    "@CHOWN_PATH@" @VDSMUSER@:@QEMUGROUP@ "${console_path}"
    "@CHMOD_PATH@" 0775 "${console_path}" > /dev/null 2>&1
    "@CHCON_PATH@" "system_u:object_r:qemu_var_run_t:s0" "${console_path}" > /dev/null 2>&1
}

_mk_transient_disks_path() {
    local transient_disks_path="@VDSMTRANSIENTDISKSDIR@"
    @MKDIR_P@ "${transient_disks_path}"
    "@CHOWN_PATH@" @VDSMUSER@:@VDSMGROUP@ "${transient_disks_path}"
}

_mk_backup_path() {
    local backup_path="@VDSMRUNBACKUPDIR@"
    @MKDIR_P@ "${backup_path}"

    # qemu create the socket in this directory
    "@CHMOD_PATH@" 0770 "${backup_path}"
    "@CHOWN_PATH@" @VDSMUSER@:@VDSMGROUP@ "${backup_path}"
    "@CHCON_PATH@" "system_u:object_r:qemu_var_run_t:s0" "${backup_path}" > /dev/null 2>&1
}

task_mkdirs(){
    _mk_data_center
    _mk_run_path
    _mk_console_path
    _mk_transient_disks_path
    _mk_backup_path
}


_free_space() {
    local pathToTest="$1"
    df -P "${pathToTest}" | awk '{print $4}'| tail -1
}

task_test_space() {
    local MIN_SPACE_KB=10000

    if [ "$(_free_space "@VDSMLOGDIR@")" -lt "${MIN_SPACE_KB}" ]; then
        echo "${prog}: low log space"
        return 1
    fi
    return 0
}


task_test_lo() {
    if ! LC_ALL=C.UTF8 "@IP_PATH@" link show lo | "@GREP_PATH@" -q UP; then
        echo "VDSMD: lo interface is down, can't run !"
        echo "VDSMD: lo interface is down, can't run !" > /dev/kmsg
        return 1
    fi
    return 0
}


task_validate_configuration(){
    "$VDSM_TOOL" validate-config
}


#### pre-start tasks end ####


#### post-stop tasks ####
task_run_final_hooks(){
    "@PYTHON@" -m "vdsm.common.hooks" after_vdsm_stop
}
#### post-stop tasks end ####


usage(){
    echo "Usage:"
    echo "vdsm_init_common.sh --pre-start|--post-stop"
}

run_tasks(){
    local tasks="$1"
    for taskName in $tasks ; do
        echo "${prog}: Running ${taskName}"
        "task_${taskName}"
        rt=$?
        if [ "$rt" -ne 0 ]; then
            echo "${prog}: stopped during execute ${taskName} task" \
                 "(task returned with error code ${rt})."
            exit 1
        fi
    done
}

case "$1" in
    --pre-start)
        run_tasks " \
            mkdirs \
            configure_vdsm_logs \
            run_init_hooks \
            check_is_configured \
            validate_configuration \
            prepare_transient_repository \
            syslog_available \
            nwfilter \
            dummybr \
            tune_system \
            test_space \
            test_lo \
            "
        ;;
    --post-stop)
        run_tasks " \
            run_final_hooks \
            "
        ;;
    --help|*)
        usage
        exit 1
        ;;
esac
